<?php
/**
 * #Celebrate Shieh
 *             ,%%%%%%%%,
 *           ,%%/\%%%%/\%%
 *          ,%%%\c "" J/%%%
 * %.       %%%%/ o  o \%%%
 * `%%.     %%%%    _  |%%%
 *  `%%     `%%%%(__Y__)%%'
 *  //       ;%%%%`\-/%%%'
 * ((       /  `%%%%%%%'
 *  \\    .'          |
 *   \\  /       \  | |
 *    \\/         ) | |
 *     \         /_ | |__
 *     (___________))))))) 攻城湿
 *
 *        _       _
 * __   _(_)_   _(_) __ _ _ __
 * \ \ / / \ \ / / |/ _` |'_ \
 *  \ V /| |\ V /| | (_| | | | |
 *   \_/ |_| \_/ |_|\__,_|_| |_|
 */
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author    walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link      http://www.workerman.net/
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 */

/**
 * 用于检测业务代码死循环或者长时间阻塞等问题
 * 如果发现业务卡死，可以将下面declare打开（去掉//注释），并执行php start.php reload
 * 然后观察一段时间workerman.log看是否有process_created_atout异常
 */

//declare(ticks=1);

use \GatewayWorker\Lib\Gateway;
use \GatewayWorker\Lib\Db;

/**
 * 主逻辑
 * 主要是处理 onConnect onMessage onClose 三个方法
 * onConnect 和 onClose 如果不需要可以不用实现并删除
 */
class Events
{

    /**
     * @param       $client_id
     * @param       $message
     *
     * @param int   $client_id
     * @param mixed $message
     *
     * @return bool|void
     * @throws Exception
     * 有消息时
     *
     */
    public static function onMessage( $client_id, $message )
    {
        // debug
        echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id session:" . json_encode($_SESSION) . " onMessage:" . $message . "\n";

        // 客户端传递的是json数据
        $message_data = json_decode($message, TRUE);
        if ( ! $message_data ) {
            return FALSE;
        }

        // 根据类型执行不同的业务
        switch ( $message_data[ 'type' ] ) {
            // 客户端回应服务端的心跳
            case 'pong':
                return FALSE;
            // 客户端登录 message格式: {type:login, name:xx, room_id:1} ，添加到客户端，广播给所有客户端xx进入聊天室
            case 'login':
                // 判断是否有房间号
                if ( ! isset($message_data[ 'room_id' ]) ) {
                    throw new \Exception("\$message_data['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
                }

                $room_id     = $message_data[ 'room_id' ];
                $client_name = htmlspecialchars($message_data[ 'client_name' ]);

                //获取头像
                $user  = Db::instance('db')->select([ 'name' ])->from('admin_users')->where("id='$client_name'")->single();
                $id    = Db::instance('db')->select([ 'avatar', ])->from('admin_users_info')->where("uid='$client_name'")->single();
                $image = Db::instance('db')->select([ 'url', ])->from('admin_files')->where("id='$id'")->single();
                if ( ! $image ) {
                    $image = '/static/admin/icon/35508.png';
                }
                // 把房间号昵称头像放到session中
                $_SESSION[ 'room_id' ]     = $room_id;
                $_SESSION[ 'client_name' ] = $user;
                $_SESSION[ 'image' ]       = $image;
                $_SESSION[ 'id' ]          = $client_name;
                //获取聊天记录
                $res = Db::instance('db')->select('*')->from('admin_chats')->where("room_id='$room_id'")->query();
                foreach ( $res as $key => $value ) {
                    $name = Db::instance('db')->select([ 'name', ])->from('admin_users')->where("id='$value[name]'")->single();
                    $id   = Db::instance('db')->select([ 'avatar', ])->from('admin_users_info')->where("uid='$value[name]'")->single();
                    $img  = Db::instance('db')->select([ 'url', ])->from('admin_files')->where("id='$id'")->single();
                    if ( ! $img ) {
                        $img = '/static/admin/icon/35508.png';
                    }
                    $res[ $key ][ 'image' ]       = $img;
                    $res[ $key ][ 'name' ]        = $name;
                    $res[ $key ][ 'content' ]     = $value[ 'content' ];
                    $res[ $key ][ 'created_at' ]  = $value[ 'created_at' ];
                    $res[ $key ][ 'room_id' ]     = $value[ 'room_id' ];
                    $res[ $key ][ 'client_name' ] = $value[ 'client_name' ];
                    if ( $value[ 'client_name' ] !== 'all' ) {
                        $res[ $key ][ 'client_names' ] = Db::instance('db')->select('name')->from('admin_users')->where("id=$value[client_name]")->single();
                    }
                }

                // 获取房间内所有用户列表
                $clients_list = Gateway::getClientSessionsByGroup($room_id);
                foreach ( $clients_list as $tmp_client_id => $item ) {
                    $clients_list[ $tmp_client_id ] = [ $item[ 'id' ], $item[ 'client_name' ], $item[ 'image' ] ];
                }
                $clients_list[ $client_id ] = [ $client_name, $user, $image ];

                // 转播给当前房间的所有客户端，xx进入聊天室 message {type:login, client_id:xx, name:xx}
                $new_message = [
                    'type'       => $message_data[ 'type' ], 'image' => $image, 'client_id' => $client_id,
                    'client_uid' => $client_name, 'client_name' => $user,
                ];
                Gateway::sendToGroup($room_id, json_encode($new_message));
                Gateway::joinGroup($client_id, $room_id);

                // 给当前用户发送用户列表
                $new_message[ 'client_list' ] = $clients_list;
                $new_message[ 'res' ]         = $res;
                Gateway::sendToCurrentClient(json_encode($new_message));
                return FALSE;

            // 客户端发言 message: {type:say, to_client_id:xx, content:xx}
            case 'say':
                // 非法请求

                if ( ! isset($_SESSION[ 'room_id' ]) ) {
                    throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
                }
                // 私聊
                if ( $message_data[ 'to_client_id' ] != 'all' ) {
                    $created_at = date('Y-m-d H:i:s');
                    $d          = Db::instance('db')->select([ 'id', ])->from('admin_users')->where("name='$message_data[to_client_name]'")->single();
                    Db::instance('db')->query("INSERT INTO admin_chats SET name='$_SESSION[id]',client_name='$d',content='$message_data[content]',created_at='$created_at',room_id='$_SESSION[room_id]'");

                    $new_message = [
                        'type'             => 'say',
                        'from_client_id'   => $client_id,
                        'from_client_name' => $_SESSION[ 'client_name' ],
                        'image'            => $_SESSION[ 'image' ],
                        'to_client_id'     => $message_data[ 'to_client_id' ],
                        'content'          => "<b>对你说: </b>" . nl2br(htmlspecialchars($message_data[ 'content' ])),
                        'created_at'       => date('Y-m-d H:i:s'),
                    ];
                    Gateway::sendToClient($message_data[ 'to_client_id' ], json_encode($new_message));
                    $new_message[ 'content' ] = "<b>你对" . $message_data[ 'to_client_name' ] . "说: </b>" . nl2br(htmlspecialchars($message_data[ 'content' ]));
                    return Gateway::sendToCurrentClient(json_encode($new_message));
                }
                else {
                    $created_at    = date('Y-m-d H:i:s');
                    $client_name_s = 'all';
                    Db::instance('db')->query("INSERT INTO admin_chats SET name='$_SESSION[id]',client_name='$client_name_s',content='$message_data[content]',created_at='$created_at',room_id='$_SESSION[room_id]'");

                    $new_message = [
                        'type'             => 'say',
                        'from_client_id'   => $client_id,
                        'from_client_name' => $_SESSION[ 'client_name' ],
                        'image'            => $_SESSION[ 'image' ],
                        'to_client_id'     => 'all',
                        'content'          => nl2br(htmlspecialchars($message_data[ 'content' ])),
                        'created_at'       => date('Y-m-d H:i:s'),
                    ];
                }
                return Gateway::sendToGroup($_SESSION[ 'room_id' ], json_encode($new_message));

        }
    }

    /**
     * 当客户端断开连接时
     *
     * @param integer $client_id 客户端id
     * @param         $client_id
     *
     * @throws Exception
     */
    public static function onClose( $client_id )
    {
        // debug
        echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id onClose:''\n";

        // 从房间的客户端列表中删除
        if ( isset($_SESSION[ 'room_id' ]) ) {
            $room_id     = $_SESSION[ 'room_id' ];
            $new_message = [
                'type'             => 'logout', 'from_client_id' => $client_id,
                'from_client_name' => $_SESSION[ 'client_name' ],
                'created_at'       => date('Y-m-d H:i:s'),
            ];
            Gateway::sendToGroup($room_id, json_encode($new_message));
        }
    }

}
